package org.ainlolcat.ainscience.statistics.handlers.hitran;

import org.ainlolcat.ainscience.Controller;
import org.ainlolcat.ainscience.UpdateListener;
import org.ainlolcat.ainscience.column.Column;
import org.ainlolcat.ainscience.column.CustomColumn;
import org.ainlolcat.ainscience.entity.Entity;
import org.ainlolcat.ainscience.matrix.MatrixFileParser;
import org.ainlolcat.ainscience.statistics.handlers.IntegralStatisticHandler;
import org.apache.log4j.Logger;
import org.jdom.Element;

import java.util.Hashtable;
import java.util.Map;

/**
 * @author ain
 *         Date: 13.01.13
 */
public class ExtractBXCustomColumn extends CustomColumn implements UpdateListener {
    private static Logger log = Logger.getLogger(ExtractBXCustomColumn.class);

    Entity entity;
    int columnId;
    Hashtable<String, String> params;
    double T;

    @Override
    public Column generateColumn(Hashtable<String, String> params, Entity entity) {
        this.entity = entity;
        this.params = params;
        setType(MatrixFileParser.MATRIX_DELIMETER_TYPE_DOUBLE);
        if (params.get("column") == null) throw new RuntimeException("no column");
        columnId = Integer.parseInt(params.get("column"));
        if (entity.getColumnById(columnId) == null){
            Controller.getInstance().addUpdateListener(this);
            return this;
        }
        String w = params.get("w");
        String mu = params.get("mu");
        Element p4i = new Element("parameters");
        if (w != null){
            Element parameter = new Element("w"); parameter.setAttribute("value", w);
            p4i.addContent(parameter);
        }
        if (mu != null){
            Element parameter = new Element("mu"); parameter.setAttribute("value", mu);
            p4i.addContent(parameter);
        }
        SpectrTStatistic handler = new SpectrTStatistic();
        Map<String, String> stat = handler.getStatistic(entity, columnId, p4i);
        T = Double.parseDouble(stat.get("T(b-x), K"));
        double[] x = handler.data[0];
        double[] generated = handler.data[2];
        double integralG = 0;
        for (int i=1; i<x.length; i++){
            if (x[i] >= 750 && x[i] <= 775){
                integralG += (x[i] - x[i-1])* (generated[i] + generated[i-1])/2;
            }
        }
        IntegralStatisticHandler iHandler = new IntegralStatisticHandler();
        p4i = new Element("parameters");
        Element range = new Element("range");
        range.setAttribute("start", "750");
        range.setAttribute("end", "775");
        range.setAttribute("name", "Integral b-x");
        p4i.addContent(range);
        stat = iHandler.getStatistic(entity, columnId, p4i);

        double integralD = Double.parseDouble(stat.get("Integral b-x"));
        double norm = integralG / integralD;

        double[] source = entity.getColumnByOrder(columnId).getDoubleRepresentation();
        int idx = entity.getXColumn("x0").findIndex(750.0);

        for (int i=0;i<source.length;i++){
            if (i < idx || i >= idx + generated.length){
                values.add(source[i]);
            } else {
                values.add(source[i] -  generated[i-idx] / norm);
            }
        }
        return this;
    }

    public void onProjectUpdate() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void onEntityUpdate(Entity entity, int action) {
        if(entity == this.entity || entity.getColumnById(columnId)!=null){
            generateColumn(params, entity);
        }
    }
}
